﻿using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using FingerPrintRecognizer.Common;
using System.Configuration;
using System.IO;
using System.Reflection;
namespace FingerPrintRecognizer
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    public class FPRecognizerService : IFPRecognizerService
    {
        #region Fields
        private string pluginDir = ".";
        private IDataProvider dbPlugin;
        private IFPRAlgorighm algorithmPlugin;

        private ILogger logger;
        #endregion

        #region Property
        public string PluginDir {
            get { return pluginDir; }
            set { this.pluginDir = value; }
        }
        #endregion

        #region Constructors
        public FPRecognizerService() {
            this.pluginDir = ".";
            this.logger = new FileLogger("C:\\FingerPrintServiceLog.log");
        }
        public FPRecognizerService(ILogger logger,string pluginDir) {
            this.logger = logger;
            this.pluginDir = pluginDir;
        }
        #endregion

        #region Methods
        public PluginInfo[] getPluginList()
        {
            DirectoryInfo dInfo = new DirectoryInfo(this.pluginDir);
            FileInfo[] files = dInfo.GetFiles("*.dll");
            Assembly ass;
            List<PluginInfo> plugins = new List<PluginInfo>();

            if (null != files)
            {
                foreach (FileInfo file in files)
                {
                    logger.debug("FILE: " + file.FullName);
                    try
                    {
                        ass = Assembly.LoadFile(file.FullName);

                        foreach (Type type in ass.GetTypes())
                        {
                            logger.debug("Type: " + type);
                            if (type.IsClass && typeof(IPlugin).IsAssignableFrom(type))
                            {
                                IPlugin plg = Activator.CreateInstance(type) as IPlugin;
                                PluginInfo pi = plg.getPluginInfo();
                                pi.DLLPath = file.FullName;
                                pi.ClassName = type.ToString();
                                plugins.Add(pi);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        logger.err(ex.Message);
                    }
                }

            }

            return plugins.ToArray();
        }
        public bool loadPlugin(PluginInfo pi)
        {
            bool success = false;
            try
            {
                Assembly ass = Assembly.LoadFile(pi.DLLPath);
                foreach (Type type in ass.GetTypes())
                {
                    if (pi.ClassName == type.ToString() && typeof(IFPRAlgorighm).IsAssignableFrom(type))
                    {
                        this.algorithmPlugin = Activator.CreateInstance(type) as IFPRAlgorighm;
                        success = true;
                    }
                    else if (pi.ClassName == type.ToString() && typeof(IDataProvider).IsAssignableFrom(type))
                    {
                        this.dbPlugin = Activator.CreateInstance(type) as IDataProvider;
                        success = true;
                    }
                }
            }
            catch (Exception ex)
            {
                logger.err(ex.Message);
            }
            return success;
        }
        #endregion

        #region IFPRecognizerService Members

        public string getAccessToken(string user, string pass)
        {
            User u;
            u = this.dbPlugin.getUserByLoginID(user);
            if (u.LoginPass == pass) { 
                //TODO: generate session token

                return "TestSessionToken[NotImplementedYet]";
            }

            return null;
        }

        public void destroyAccessToken(string accessToken)
        {
            throw new NotImplementedException();
        }

        public Person getPersonById(string accessToken, int id)
        {
            throw new NotImplementedException();
        }

        public Person getPersonByNationalId(string accessToken, string nationalID)
        {
            if (this.dbPlugin == null) return null;
            return this.dbPlugin.getPersonByNationalID(nationalID);
        }

        public Person[] getPersons(string accessToken, int itemPerPage, int pageNo)
        {
            throw new NotImplementedException();
        }

        public bool savePerson(string accessToken, Person person)
        {
            this.dbPlugin.savePerson(person);
            return true;
        }

        public PluginInfo[] getPluginList(string accessToken)
        {
            return getPluginList();


        }

        public bool loadPlugin(string accessToken, PluginInfo pi)
        {
            return loadPlugin(pi);
        }
        #endregion

    }


}
